import { TMakeASTNode, CompilerConfig, FunctionEvaluator, EvaluationContext, CompilerError } from './types';
import * as fs from 'fs';
import * as path from 'path';
import { TMakeCompiler } from './compiler';
import * as crypto from 'crypto';


export enum PluginLifecycleEvent {
  
  BEFORE_INIT = 'beforeInit',
  AFTER_INIT = 'afterInit',
  
  
  BEFORE_COMPILE = 'beforeCompile',
  AFTER_PARSE = 'afterParse',
  BEFORE_TRANSFORM = 'beforeTransform',
  AFTER_TRANSFORM = 'afterTransform',
  BEFORE_GENERATE = 'beforeGenerate',
  AFTER_GENERATE = 'afterGenerate',
  AFTER_COMPILE = 'afterCompile',
  
  
  BEFORE_BUILD = 'beforeBuild',
  AFTER_BUILD = 'afterBuild',
  
  
  BEFORE_CLEAN = 'beforeClean',
  AFTER_CLEAN = 'afterClean',
  
  
  ON_ERROR = 'onError',
  ON_WARNING = 'onWarning'
}


export interface PluginMetadata {
  
  name: string;
  
  version: string;
  
  description?: string;
  
  author?: string;
  
  dependencies?: string[];
  
  config?: Record<string, any>;
  
  isCore?: boolean;
}


export interface ASTManipulator {
  
  createNode(type: string, value?: any, params?: any[], line?: number, column?: number): TMakeASTNode;
  
  
  findNode(ast: TMakeASTNode | TMakeASTNode[], predicate: (node: TMakeASTNode) => boolean): TMakeASTNode | null;
  
  
  findAllNodes(ast: TMakeASTNode | TMakeASTNode[], predicate: (node: TMakeASTNode) => boolean): TMakeASTNode[];
  
  
  replaceNode(ast: TMakeASTNode | TMakeASTNode[], target: TMakeASTNode, replacement: TMakeASTNode): boolean;
  
  
  modifyNode(node: TMakeASTNode, updates: Partial<TMakeASTNode>): void;
  
  
  traverseNode(node: TMakeASTNode, visitor: (node: TMakeASTNode, parent?: TMakeASTNode) => void, parent?: TMakeASTNode): void;
}


export interface BuildTargetInfo {
  
  name: string;
  
  description?: string;
  
  type?: string;
  
  extensions?: string[];
  
  isDefault?: boolean;
  
  priority?: number;
}


export interface BuildTargetHandler extends BuildTargetInfo {
  
  build: (api: PluginAPI, sourceFiles: string[], options: Record<string, any>) => Promise<boolean>;
  
  clean?: (api: PluginAPI, options: Record<string, any>) => Promise<boolean>;
  
  getConfig?: (api: PluginAPI, options: Record<string, any>) => Record<string, any>;
}


export interface PluginAPI {
  
  compiler: TMakeCompiler;
  
  config: CompilerConfig;
  
  ast: ASTManipulator;
  
  /**
   * 注册一个函数到TMake编译器中
   * @param name 函数名称
   * @param handler 函数处理函数
   * @param description 函数描述（可选）
   * @param paramDescriptions 参数描述对象，格式为{参数名:"类型"}（可选）
   */
  registerFunction(name: string, handler: (node: TMakeASTNode, context: EvaluationContext) => any, description?: string, paramDescriptions?: Record<string, string>): void;
  
  registerBuildTarget(target: BuildTargetHandler): void;
  
  getRegisteredBuildTargets(): BuildTargetInfo[];
  
  getDefaultBuildTarget(): string;
  
  setDefaultBuildTarget(targetName: string): boolean;
  
  executeBuildTarget(targetName: string, sourceFiles: string[], options?: Record<string, any>): Promise<boolean>;
  
  getProjectDir(): string;
  
  readFile(filePath: string): Promise<string>;
  
  writeFile(filePath: string, content: string): Promise<void>;
  
  // 为了向后兼容，保留同步版本的文件操作方法
  readFileSync?(filePath: string): string;
  
  writeFileSync?(filePath: string, content: string): void;
  
  addError(error: Omit<CompilerError, 'type'>): void;
  
  addWarning(message: string, line?: number, column?: number): void;
  
  getConfig<T = any>(): T;
  
  executeCommand(command: string, options?: {
    cwd?: string;
    env?: Record<string, string>;
  }): Promise<{ success: boolean; stdout: string; stderr: string }>;
  
  // 缓存操作API
  /**
   * 存储缓存项
   * @param key 缓存键名
   * @param value 缓存值
   * @param options 可选配置，如过期时间
   */
  setCacheItem(key: string, value: any, options?: { expireTime?: number }): void;
  
  /**
   * 获取缓存项
   * @param key 缓存键名
   * @returns 缓存值，如果不存在则返回undefined
   */
  getCacheItem<T = any>(key: string): T | undefined;
  
  /**
   * 检查缓存项是否存在
   * @param key 缓存键名
   * @returns 是否存在
   */
  hasCacheItem(key: string): boolean;
  
  /**
   * 删除缓存项
   * @param key 缓存键名
   */
  removeCacheItem(key: string): void;
  
  /**
   * 清除所有缓存项
   */
  clearCache(): void;
  
  /**
   * 获取所有缓存键
   * @returns 缓存键数组
   */
  getAllCacheKeys(): string[];
  
  /**
   * 验证缓存是否有效
   * @returns 缓存是否有效
   */
  isValidCache(): boolean;
}


export interface PluginHooks {
  [PluginLifecycleEvent.BEFORE_INIT]?: (api: PluginAPI) => void;
  [PluginLifecycleEvent.AFTER_INIT]?: (api: PluginAPI) => void;
  [PluginLifecycleEvent.BEFORE_COMPILE]?: (api: PluginAPI, sourceCode: string) => void;
  [PluginLifecycleEvent.AFTER_PARSE]?: (api: PluginAPI, ast: TMakeASTNode[]) => void;
  [PluginLifecycleEvent.BEFORE_TRANSFORM]?: (api: PluginAPI, ast: TMakeASTNode[]) => void;
  [PluginLifecycleEvent.AFTER_TRANSFORM]?: (api: PluginAPI, ast: TMakeASTNode[]) => void;
  [PluginLifecycleEvent.BEFORE_GENERATE]?: (api: PluginAPI, ast: TMakeASTNode[]) => void;
  [PluginLifecycleEvent.AFTER_GENERATE]?: (api: PluginAPI, output: string) => void;
  [PluginLifecycleEvent.AFTER_COMPILE]?: (api: PluginAPI, success: boolean) => void;
  [PluginLifecycleEvent.BEFORE_BUILD]?: (api: PluginAPI, options: any) => void;
  [PluginLifecycleEvent.AFTER_BUILD]?: (api: PluginAPI, success: boolean) => void;
  [PluginLifecycleEvent.BEFORE_CLEAN]?: (api: PluginAPI) => void;
  [PluginLifecycleEvent.AFTER_CLEAN]?: (api: PluginAPI, success: boolean) => void;
  [PluginLifecycleEvent.ON_ERROR]?: (api: PluginAPI, error: CompilerError) => void;
  [PluginLifecycleEvent.ON_WARNING]?: (api: PluginAPI, warning: string) => void;
}


export interface TMakePlugin extends PluginHooks {
  
  metadata: PluginMetadata;
  
  
  init?: (api: PluginAPI) => void;
}


// 缓存元数据接口定义，与index.ts保持一致
export interface CacheMetadata {
  sourceHashes: Record<string, string>;
  packageHashes: Record<string, string>;
  tmakeHashes: Record<string, string>;
  outputSrcHashes: Record<string, string>;
  timestamp: number;
}

// 缓存项接口定义
interface CacheItem {
  value: any;
  expireTime?: number;
  hash?: string;
}

export class PluginSystem {
  private plugins: Map<string, { plugin: TMakePlugin; api: PluginAPI }> = new Map();
  private compiler: TMakeCompiler;
  private astManipulator: ASTManipulator;
  // 缓存存储，使用Map存储缓存项
  private cache: Map<string, CacheItem> = new Map();
  // 缓存元数据存储路径
  private cacheMetadataPath: string;
  // 缓存元数据
  private cacheMetadata: CacheMetadata | null = null;
  
  constructor(compiler: TMakeCompiler) {
    this.compiler = compiler;
    this.astManipulator = this.createASTManipulator();
    // 设置缓存元数据存储路径
    this.cacheMetadataPath = path.join(process.cwd(), '.tmake', 'cache', 'plugin-cache-metadata.json');
    // 确保缓存目录存在
    this.ensureCacheDirExists();
    // 加载缓存元数据
    this.cacheMetadata = this.loadCacheMetadata();
  }

  private ensureCacheDirExists(): void {
    const cacheDir = path.dirname(this.cacheMetadataPath);
    if (!fs.existsSync(cacheDir)) {
      fs.mkdirSync(cacheDir, { recursive: true });
    }
  }

  // 计算文件哈希值
  private getFileHash(filePath: string): string {
    try {
      const content = fs.readFileSync(filePath, 'utf8');
      return crypto.createHash('md5').update(content).digest('hex');
    } catch (error) {
      // 文件不存在或读取失败时返回空字符串
      return '';
    }
  }

  // 计算目录中所有文件的哈希值
  private getDirectoryFilesHash(dirPath: string): Record<string, string> {
    const hashes: Record<string, string> = {};
    
    try {
      if (fs.existsSync(dirPath)) {
        const files = fs.readdirSync(dirPath, { recursive: true });
        
        for (const file of files) {
          const filePath = path.join(dirPath, String(file));
          const stat = fs.statSync(filePath);
          
          if (stat.isFile()) {
            const relativePath = path.relative(dirPath, filePath).replace(/\\/g, '/');
            hashes[relativePath] = this.getFileHash(filePath);
          }
        }
      }
    } catch (error) {
      // 目录访问失败时忽略错误
    }
    
    return hashes;
  }

  // 保存缓存元数据
  private saveCacheMetadata(metadata: CacheMetadata): void {
    try {
      this.ensureCacheDirExists();
      fs.writeFileSync(this.cacheMetadataPath, JSON.stringify(metadata, null, 2), 'utf8');
      this.cacheMetadata = metadata;
    } catch (error) {
      // 保存失败时忽略错误
    }
  }

  // 加载缓存元数据
  private loadCacheMetadata(): CacheMetadata | null {
    try {
      if (fs.existsSync(this.cacheMetadataPath)) {
        const content = fs.readFileSync(this.cacheMetadataPath, 'utf8');
        return JSON.parse(content) as CacheMetadata;
      }
    } catch (error) {
      // 加载失败时返回null
    }
    return null;
  }

  // 比较两个哈希映射是否相等
  private areHashMapsEqual(map1: Record<string, string>, map2: Record<string, string>): boolean {
    const keys1 = Object.keys(map1);
    const keys2 = Object.keys(map2);
    
    if (keys1.length !== keys2.length) {
      return false;
    }
    
    for (const key of keys1) {
      if (map1[key] !== map2[key]) {
        return false;
      }
    }
    
    return true;
  }

  // 验证输出源文件哈希值
  private validateOutputSrcHashes(hashes: Record<string, string>): boolean {
    for (const [filePath, expectedHash] of Object.entries(hashes)) {
      const actualHash = this.getFileHash(filePath);
      if (actualHash !== expectedHash) {
        return false;
      }
    }
    return true;
  }
  
  private visitNodeChildren(node: TMakeASTNode, callback: (child: TMakeASTNode) => void): void {
    if (node.children && Array.isArray(node.children)) {
      for (const child of node.children) {
        callback(child);
      }
    }
    
    // 处理params数组中的节点对象
    if (node.params && Array.isArray(node.params)) {
      for (const param of node.params) {
        if (param && typeof param === 'object' && param.type) {
          callback(param);
        }
      }
    }
  }
  
  private createASTManipulator(): ASTManipulator {
    return {
      createNode: (type: string, value?: any, params?: any[], line?: number, column?: number): TMakeASTNode => ({
        type,
        value,
        params,
        line,
        column
      }),
      
      findNode: (ast: TMakeASTNode | TMakeASTNode[], predicate: (node: TMakeASTNode) => boolean): TMakeASTNode | null => {
        if (Array.isArray(ast)) {
          for (const node of ast) {
            const result = this.findNodeRecursive(node, predicate);
            if (result) return result;
          }
          return null;
        }
        return this.findNodeRecursive(ast, predicate);
      },
      
      findAllNodes: (ast: TMakeASTNode | TMakeASTNode[], predicate: (node: TMakeASTNode) => boolean): TMakeASTNode[] => {
        const results: TMakeASTNode[] = [];
        
        if (Array.isArray(ast)) {
          for (const node of ast) {
            this.findAllNodesRecursive(node, predicate, results);
          }
        } else {
          this.findAllNodesRecursive(ast, predicate, results);
        }
        
        return results;
      },
      
      replaceNode: (ast: TMakeASTNode | TMakeASTNode[], target: TMakeASTNode, replacement: TMakeASTNode): boolean => {
        if (Array.isArray(ast)) {
          for (let i = 0; i < ast.length; i++) {
            if (ast[i] === target) {
              ast[i] = replacement;
              return true;
            }
            if (this.replaceNodeRecursive(ast[i], target, replacement)) {
              return true;
            }
          }
          return false;
        }
        return this.replaceNodeRecursive(ast, target, replacement);
      },
      
      modifyNode: (node: TMakeASTNode, updates: Partial<TMakeASTNode>): void => {
        Object.assign(node, updates);
      },
      
      traverseNode: (node: TMakeASTNode, visitor: (node: TMakeASTNode, parent?: TMakeASTNode) => void, parent?: TMakeASTNode): void => {
        // 只调用一次visitor，避免重复访问
        visitor(node, parent);
        
        const traverseChild = (childNode: TMakeASTNode, childParent?: TMakeASTNode) => {
            // 递归遍历子节点，visitor会在这里被调用
            // 由于traverseNode是当前对象的方法，直接调用visitor处理子节点
            visitor(childNode, childParent);
            // 遍历子节点的子节点
            this.visitNodeChildren(childNode, (grandChild) => {
                traverseChild(grandChild, childNode);
            });
          };
        
        // 使用统一的辅助方法遍历子节点
        this.visitNodeChildren(node, (child) => traverseChild(child, node));
      }
    };
  }
  
  
  private findNodeRecursive(node: TMakeASTNode, predicate: (node: TMakeASTNode) => boolean): TMakeASTNode | null {
    if (predicate(node)) return node;
    
    // 使用统一的辅助方法遍历子节点
    let result: TMakeASTNode | null = null;
    this.visitNodeChildren(node, (child) => {
      if (!result) { // 只有在还没找到结果时才继续搜索
        result = this.findNodeRecursive(child, predicate);
      }
    });
    
    return result;
  }
  
  private findAllNodesRecursive(node: TMakeASTNode, predicate: (node: TMakeASTNode) => boolean, results: TMakeASTNode[]): void {
    if (predicate(node)) results.push(node);
    
    // 使用统一的辅助方法遍历子节点
    this.visitNodeChildren(node, (child) => {
      this.findAllNodesRecursive(child, predicate, results);
    });
  }
  
  private replaceNodeRecursive(node: TMakeASTNode, target: TMakeASTNode, replacement: TMakeASTNode): boolean {
    // 检查children数组
    if (node.children && Array.isArray(node.children)) {
      for (let i = 0; i < node.children.length; i++) {
        if (node.children[i] === target) {
          node.children[i] = replacement;
          return true;
        }
        if (this.replaceNodeRecursive(node.children[i], target, replacement)) {
          return true;
        }
      }
    }
    
    // 检查params数组
    if (node.params && Array.isArray(node.params)) {
      for (let i = 0; i < node.params.length; i++) {
        if (node.params[i] === target) {
          node.params[i] = replacement;
          return true;
        }
        if (node.params[i] && typeof node.params[i] === 'object' && node.params[i].type) {
          if (this.replaceNodeRecursive(node.params[i], target, replacement)) {
            return true;
          }
        }
      }
    }
    
    return false;
  }
  
  
  private buildTargets: Map<string, BuildTargetHandler> = new Map();
  private defaultBuildTarget: string = '';

  
  private createPluginAPI(plugin: TMakePlugin): PluginAPI {
    const pluginName = plugin.metadata?.name || 'unknown';
    return {
      compiler: this.compiler,
      config: this.compiler['config'], 
      ast: this.astManipulator,
      
      registerFunction: (name: string, handler: (node: TMakeASTNode, context: EvaluationContext) => any, description?: string, paramDescriptions?: Record<string, string>): void => {
        const extension = {
          name,
          pluginName, // 添加插件名称到extension对象
          handler: (node: TMakeASTNode, config: CompilerConfig, evaluate: FunctionEvaluator, context: EvaluationContext) => {
            try {
              return handler(node, context);
            } catch (error: any) {
              throw new Error(`插件函数 ${name} 执行失败: ${error.message}`);
            }
          }
        };
        
        // 添加描述信息
        if (description) {
          (extension as any).description = description;
        }
        
        // 处理参数描述
        if (paramDescriptions) {
          (extension as any).parameters = Object.entries(paramDescriptions).map(([paramName, paramType]) => ({
            name: paramName,
            type: paramType,
            description: `${paramName} 参数`,
            required: true
          }));
        }
        
        this.compiler.registerExtension(extension);
      },

      registerBuildTarget: (target: BuildTargetHandler): void => {
        if (this.buildTargets.has(target.name)) {
            console.warn(`编译目标 ${target.name} 已存在，将被覆盖`);
          }
        this.buildTargets.set(target.name, target);
        
        if (target.isDefault || (this.defaultBuildTarget === '' && target.priority !== undefined && target.priority > 0)) {
          this.defaultBuildTarget = target.name;
        }
      },

      getRegisteredBuildTargets: (): BuildTargetInfo[] => {
        return Array.from(this.buildTargets.values()).map(target => ({
          name: target.name,
          description: target.description,
          type: target.type,
          extensions: target.extensions,
          isDefault: target.name === this.defaultBuildTarget,
          priority: target.priority
        }));
      },
      
      getDefaultBuildTarget: (): string => {
        return this.defaultBuildTarget;
      },
      
      setDefaultBuildTarget: (targetName: string): boolean => {
        if (this.buildTargets.has(targetName)) {
          this.defaultBuildTarget = targetName;
          return true;
        }
        return false;
      },

      executeBuildTarget: async (targetName: string, sourceFiles: string[], options: Record<string, any> = {}): Promise<boolean> => {
        const target = this.buildTargets.get(targetName);
        if (!target) {
            console.error(`编译目标 ${targetName} 不存在`);
          return false;
        }

        try {
          // 移除调试日志
          let targetOptions = options;
            if (target.getConfig) {
              
              const api = this.createPluginAPI({
                metadata: { name: 'build-target-system' }
              } as TMakePlugin);
              targetOptions = { ...options, ...target.getConfig(api, options) };
            }
          
          
          if (target.extensions && sourceFiles.length > 0) {
            const supportedFiles = sourceFiles.filter(file => 
              typeof file === 'string' && file && target.extensions!.some(ext => file.endsWith(ext))
            );
            if (supportedFiles.length === 0) {
              console.warn(`没有找到支持的文件扩展名 ${target.extensions!.join(', ')}`);
              return false;
            }
            
              const api = this.createPluginAPI({
                metadata: { name: 'build-target-system' }
              } as TMakePlugin);
              return await target.build(api, supportedFiles, targetOptions);
          }
          
          
          const api = this.createPluginAPI({
            metadata: { name: 'build-target-system' }
          } as TMakePlugin);
          return await target.build(api, sourceFiles, targetOptions);
        } catch (error: any) {
            console.error(`执行编译目标 ${targetName} 失败: ${error.message}`);
          return false;
        }
      },
      
      getProjectDir: (): string => {
        return process.cwd();
      },
      
      readFile: async (filePath: string): Promise<string> => {
        return await fs.promises.readFile(filePath, 'utf-8');
      },
      
      writeFile: async (filePath: string, content: string): Promise<void> => {
        const dirPath = path.dirname(filePath);
        try {
          // 尝试创建目录，如果已存在不会抛出错误
          await fs.promises.mkdir(dirPath, { recursive: true });
        } catch (error: any) {
          // 如果错误不是因为目录已存在，则抛出
          if (error.code !== 'EEXIST') {
            throw error;
          }
        }
        await fs.promises.writeFile(filePath, content, 'utf-8');
      },
      
      // 为向后兼容提供同步版本的文件操作方法
      readFileSync: (filePath: string): string => {
        return fs.readFileSync(filePath, 'utf-8');
      },
      
      writeFileSync: (filePath: string, content: string): void => {
        const dirPath = path.dirname(filePath);
        if (!fs.existsSync(dirPath)) {
          fs.mkdirSync(dirPath, { recursive: true });
        }
        fs.writeFileSync(filePath, content, 'utf-8');
      },
      
      addError: (error: Omit<CompilerError, 'type'>): void => {
        const fullError: CompilerError = {
          type: 'runtime',
          ...error
        };
        (this.compiler as any).addError(fullError);
      },
      
      addWarning: (message: string, line?: number, column?: number): void => {
        (this.compiler as any).addWarning(message);
      },
      
      getConfig: <T = any>(): T => {
        return plugin.metadata.config as T || {} as T;
      },

      executeCommand: async (command: string, options: {
        cwd?: string;
        env?: Record<string, string>;
      } = {}): Promise<{ success: boolean; stdout: string; stderr: string }> => {
        const { exec } = require('child_process');
        
        return new Promise((resolve) => {
          exec(command, {
            cwd: options.cwd || process.cwd(),
            env: {
              ...process.env,
              ...options.env
            }
          }, (error: any, stdout: string, stderr: string) => {
            resolve({
              success: error === null,
              stdout: stdout.trim(),
              stderr: stderr.trim()
            });
          });
        });
      },
      
      // 缓存操作API实现，基于文件哈希进行持久化存储
      setCacheItem: (key: string, value: any, options?: { expireTime?: number }): void => {
        // 计算值的哈希，用于验证缓存有效性
        const valueStr = JSON.stringify(value);
        const valueHash = crypto.createHash('md5').update(valueStr).digest('hex');
        
        const cacheItem: CacheItem = {
          value,
          expireTime: options?.expireTime,
          hash: valueHash
        };
        
        this.cache.set(key, cacheItem);
        
        // 更新缓存元数据
        this.updateCacheMetadata();
      },
      
      getCacheItem: <T = any>(key: string): T | undefined => {
        const cacheItem = this.cache.get(key);
        
        // 如果缓存项不存在，直接返回undefined
        if (!cacheItem) {
          return undefined;
        }
        
        // 检查是否过期
        if (cacheItem.expireTime && Date.now() > cacheItem.expireTime) {
          // 过期则移除并返回undefined
          this.cache.delete(key);
          this.updateCacheMetadata();
          return undefined;
        }
        
        // 验证缓存内容的完整性
        const valueStr = JSON.stringify(cacheItem.value);
        const currentHash = crypto.createHash('md5').update(valueStr).digest('hex');
        
        if (cacheItem.hash && currentHash !== cacheItem.hash) {
          // 哈希不匹配，说明内容被篡改，删除缓存项
          this.cache.delete(key);
          this.updateCacheMetadata();
          return undefined;
        }
        
        return cacheItem.value as T;
      },
      
      hasCacheItem: (key: string): boolean => {
        const cacheItem = this.cache.get(key);
        if (!cacheItem) {
          return false;
        }
        if (cacheItem.expireTime && Date.now() > cacheItem.expireTime) {
          this.cache.delete(key);
          this.updateCacheMetadata();
          return false;
        }
        
        // 验证缓存内容的完整性
        const valueStr = JSON.stringify(cacheItem.value);
        const currentHash = crypto.createHash('md5').update(valueStr).digest('hex');
        
        if (cacheItem.hash && currentHash !== cacheItem.hash) {
          // 哈希不匹配，说明内容被篡改，删除缓存项
          this.cache.delete(key);
          this.updateCacheMetadata();
          return false;
        }
        
        return true;
      },
      
      removeCacheItem: (key: string): void => {
        this.cache.delete(key);
        this.updateCacheMetadata();
      },
      
      clearCache: (): void => {
        this.cache.clear();
        
        // 清除缓存元数据文件
        if (fs.existsSync(this.cacheMetadataPath)) {
          try {
            fs.unlinkSync(this.cacheMetadataPath);
          } catch (error) {
            // 删除失败时忽略错误
          }
        }
        
        this.cacheMetadata = null;
      },
      
      getAllCacheKeys: (): string[] => {
        // 先清理过期的缓存项
        const now = Date.now();
        let hasChanges = false;
        
        for (const [key, item] of this.cache.entries()) {
          if (item.expireTime && now > item.expireTime) {
            this.cache.delete(key);
            hasChanges = true;
            continue;
          }
          
          // 验证缓存内容的完整性
          const valueStr = JSON.stringify(item.value);
          const currentHash = crypto.createHash('md5').update(valueStr).digest('hex');
          
          if (item.hash && currentHash !== item.hash) {
            // 哈希不匹配，说明内容被篡改，删除缓存项
            this.cache.delete(key);
            hasChanges = true;
          }
        }
        
        // 如果有更改，更新缓存元数据
        if (hasChanges) {
          this.updateCacheMetadata();
        }
        
        // 返回所有有效的缓存键
        return Array.from(this.cache.keys());
      },
      
      // 额外添加的方法：验证缓存是否有效
      isValidCache: (): boolean => {
        if (!this.cacheMetadata) {
          return false;
        }
        
        // 计算当前的源代码哈希
        const projectDir = process.cwd();
        const currentSourceHashes = this.getDirectoryFilesHash(path.join(projectDir, 'src'));
        
        // 比较哈希值
        return this.areHashMapsEqual(currentSourceHashes, this.cacheMetadata.sourceHashes);
      }
    };
  }
  
  // 更新缓存元数据
  private updateCacheMetadata(): void {
    const projectDir = process.cwd();
    
    // 计算各种文件的哈希值
    const sourceHashes = this.getDirectoryFilesHash(path.join(projectDir, 'src'));
    const packageHashes = this.getDirectoryFilesHash(path.join(projectDir, 'package'));
    const tmakeHashes = this.getDirectoryFilesHash(path.join(projectDir, '.tmake'));
    
    // 构建缓存元数据
    const metadata: CacheMetadata = {
      sourceHashes,
      packageHashes,
      tmakeHashes,
      outputSrcHashes: {}, // 插件系统不直接生成输出文件，所以这里为空
      timestamp: Date.now()
    };
    
    // 保存缓存元数据
    this.saveCacheMetadata(metadata);
  }
  
  
  public loadPlugin(pluginModule: any): boolean {
    try {
      let plugin: TMakePlugin;
      
      if (pluginModule.default && typeof pluginModule.default === 'object') {
        plugin = pluginModule.default;
      } else if (typeof pluginModule === 'object') {
        plugin = pluginModule;
      } else {
        const api = this.createPluginAPI({ metadata: { name: 'plugin-system' } } as TMakePlugin);
        api.addError({
          message: '无效的插件模块格式'
        });
        return false;
      }
      
      if (!plugin.metadata || !plugin.metadata.name) {
        const api = this.createPluginAPI({ metadata: { name: 'plugin-system' } } as TMakePlugin);
        api.addError({
          message: '插件缺少必要的元数据'
        });
        return false;
      }
      
      const pluginName = plugin.metadata.name;
      
      if (this.plugins.has(pluginName)) {
        const api = this.createPluginAPI({ metadata: { name: 'plugin-system' } } as TMakePlugin);
        api.addWarning(`插件 ${pluginName} 已加载，跳过`);
        return true;
      }
      
      const api = this.createPluginAPI(plugin);
      
      this.plugins.set(pluginName, { plugin, api });
      
      if (plugin.init) {
        try {
          plugin.init(api);
        } catch (error: any) {
          api.addError({
            message: `插件 ${pluginName} 初始化失败: ${error.message}`
          });
          this.plugins.delete(pluginName);
          return false;
        }
      }
      
      return true;
    } catch (error: any) {
      const api = this.createPluginAPI({ metadata: { name: 'plugin-system' } } as TMakePlugin);
      api.addError({
        message: `加载插件失败: ${error.message}`
      });
      return false;
    }
  }
  
  
  public async loadPluginFromFile(filePath: string): Promise<boolean> {
    try {
      const api = this.createPluginAPI({ metadata: { name: 'plugin-system' } } as TMakePlugin);
      try {
        await fs.promises.access(filePath);
      } catch (error) {
        api.addError({
          message: `插件文件不存在: ${filePath}`
        });
        return false;
      }
      
      if (require.cache[require.resolve(filePath)]) {
        delete require.cache[require.resolve(filePath)];
      }

      const pluginModule = require(filePath);
      return this.loadPlugin(pluginModule);
    } catch (error: any) {
      const api = this.createPluginAPI({ metadata: { name: 'plugin-system' } } as TMakePlugin);
      api.addError({
          message: `从文件加载插件失败 ${filePath}: ${error.message}`
        });
      return false;
    }
  }
  
  public async loadPluginsFromDirectory(dirPath: string): Promise<void> {
    try {
      const api = this.createPluginAPI({ metadata: { name: 'plugin-system' } } as TMakePlugin);
      try {
        await fs.promises.access(dirPath);
      } catch (error) {
        api.addWarning(`插件目录不存在: ${dirPath}`);
        return;
      }
      
      const files = await fs.promises.readdir(dirPath);
      
      // 使用Promise.all并行加载所有插件
      const loadPromises = files
        .filter(file => file.endsWith('.js') || file.endsWith('.ts'))
        .map(file => this.loadPluginFromFile(path.join(dirPath, file)));
      
      await Promise.all(loadPromises);
    } catch (error: any) {
      const api = this.createPluginAPI({ metadata: { name: 'plugin-system' } } as TMakePlugin);
      api.addError({
          message: `从目录加载插件失败 ${dirPath}: ${error.message}`
        });
    }
  }
  
  
  public emitEvent(event: PluginLifecycleEvent, ...args: any[]): void {
    for (const [pluginName, { plugin, api }] of this.plugins) {
      const hook = plugin[event];
      if (typeof hook === 'function') {
        try {
          if (args.length === 0) {
            (hook as Function)(api);
          } else if (args.length === 1) {
            (hook as Function)(api, args[0]);
          } else if (args.length === 2) {
            (hook as Function)(api, args[0], args[1]);
          } else {
            (hook as Function)(api, ...args);
          }
        } catch (error: any) {
          console.error(`插件 ${pluginName} 在处理事件 ${event} 时出错: ${error.message}`);
        }
      }
    }
  }
  
  
  public getLoadedPlugins(): { name: string; version: string; description?: string }[] {
    const plugins: { name: string; version: string; description?: string }[] = [];
    
    for (const { plugin } of this.plugins.values()) {
      plugins.push({
        name: plugin.metadata.name,
        version: plugin.metadata.version || '1.0.0',
        description: plugin.metadata.description
      });
    }
    
    return plugins;
  }
  
  
  public hasPlugin(name: string): boolean {
    return this.plugins.has(name);
  }
  
  
  public getPluginConfig(name: string): any {
    const pluginInfo = this.plugins.get(name);
    return pluginInfo?.plugin.metadata.config;
  }
  
  
  public setPluginConfig(name: string, config: Record<string, any>): boolean {
    const pluginInfo = this.plugins.get(name);
    if (pluginInfo) {
      pluginInfo.plugin.metadata.config = config;
      return true;
    }
    return false;
  }
  
  
  public unloadPlugin(name: string): boolean {
    return this.plugins.delete(name);
  }
  
  
  public clearPlugins(): void {
    this.plugins.clear();
  }

  /**
   * 获取所有通过插件注册的函数信息
   * 用于生成函数描述文件
   */
  public getRegisteredFunctions(): Array<{name: string, plugin: string}> {
    const functions: Array<{name: string, plugin: string}> = [];
    
    // 通过编译器实例获取所有函数映射
    const compilerFunctions = (this.compiler as any).extensions || new Map();
    
    // 处理Map类型的extensions
    if (compilerFunctions instanceof Map) {
      for (const [funcName, extension] of compilerFunctions.entries()) {
        // 直接从extension对象获取pluginName，如果没有则默认为'unknown'
        const pluginName = (extension as any).pluginName || 'unknown';
        
        functions.push({
          name: funcName,
          plugin: pluginName
        });
      }
    } else {
      // 兼容旧的对象格式
      for (const [funcName, extension] of Object.entries(compilerFunctions)) {
        // 检查是否是通过插件注册的函数，尝试推断插件来源
        let pluginName = 'unknown';
        
        // 遍历插件，查找可能注册了这个函数的插件
        for (const [name, { plugin }] of this.plugins) {
          if (funcName.includes(name.toLowerCase())) {
            pluginName = name;
            break;
          }
        }
        
        functions.push({
          name: funcName,
          plugin: pluginName
        });
      }
    }
    
    return functions;
  }
}


export function createPluginTemplate(metadata: PluginMetadata): TMakePlugin {
  return {
    metadata,
    init: (api) => {
    }
  };
}


export function createPluginManager(compiler: TMakeCompiler): PluginSystem {
  return new PluginSystem(compiler);
}